package org;

import java.io.*;
import java.util.*;

import user.*;

public class FileUtils {
	RandomAccessFile iof;
	
	public FileUtils(File file) {
		try {
			iof=new RandomAccessFile(file,"rw");
			//iof.writeBytes("check");
		} catch(IOException iox) {
			System.err.println("Could not open File");
		}
		
		try {
			User.setCount(iof.readInt());
			System.out.println(User.getCount()+" users registered");
		} catch (IOException e) {
			System.err.println("No Users registered");
		}
	}

	public void addUser(User user) throws IOException, UnsupportedOperationException{
		
		try {
			user=parseUser(user.getName());
			if(user!=null) {
				User.failed();
				throw new UnsupportedOperationException("User does already exist");
			}
		}
		catch(UserException ux) {
			System.out.println("User does not yet exist");
		}
		
		
		//Refresh user count
		iof.seek(0);
		iof.writeInt(User.getCount());
		//Write user data
		iof.seek(iof.length());
		iof.writeInt(user.getId());
		iof.writeInt(user.getName().length());
		iof.writeBytes(user.getName());
		iof.writeInt(user.getPassword().length());
		iof.writeBytes(PWCrypt.scramblePW(user));
	}
	
	public List<User> getAllUsers() throws IOException {
		List<User> users=new ArrayList<User>();
		iof.seek(4);
		String name=null,password=null;
		int id=0;
		byte[] bf=null;
		for(int i=0;i<User.getCount();i++) {
			id=iof.readInt();
			bf=new byte[iof.readInt()];
			iof.read(bf,0,bf.length);
			name=new String(bf);
			bf=new byte[iof.readInt()];
			iof.read(bf,0,bf.length);
			password=PWCrypt.unscramblePW(new String(bf),name,id);
			users.add(User.reconstruct(id,name,password));
		}
		return users;
	}
	
	//Parse User by Name
	public User parseUser(String name) throws IOException,UserException {
		name=name.trim();
		int id=0;
		String getname="";
		String password=null;
		iof.seek(4);
		byte[] bf;
		while(!getname.equals(name) && (iof.getFilePointer()<iof.length()) ){
			id=iof.readInt();
			bf=new byte[iof.readInt()];
			iof.read(bf,0,bf.length);
			getname=new String(bf);
			bf=new byte[iof.readInt()];
			iof.read(bf,0,bf.length);
			password=PWCrypt.unscramblePW(new String(bf),name,id);
		}
		
		/*if(getname.equals(name)) {
			bf=new byte[iof.readInt()];
			iof.read(bf,0,bf.length);
			password=new String(bf);
		}*/
		User user;
		if(getname.equals(name))
			user=User.reconstruct(id,name,password);
		else {
			user=null;
			throw new UserException("User not Found");
		}
		return user;
	}
	
	//Parse User by ID
	public User parseUser(int id) throws IOException {
		int getid;
		iof.seek(4);
		getid=iof.readInt();
		//find user id
		while(getid!=id) {
			iof.skipBytes(iof.readInt());
			iof.skipBytes(iof.readInt());
			getid=iof.readInt();
		}
		//parse user information
		String name=null;
		String password=null;
		if(getid==id && (iof.getFilePointer()<iof.length()) ) {
			int len=iof.readInt();
			byte[] bf=new byte[len];
			iof.read(bf, 0, len);
			name = new String(bf);
			
			len=iof.readInt();
			bf=new byte[len];
			iof.read(bf, 0, len);
			password=PWCrypt.unscramblePW(new String(bf),name,id);
		}
		
		User user=User.reconstruct(id,name,password);
		return user;
	}
	
	//Get Number of total registered Users
	//Set pointer back to original position
	public int getUserNumber() {
		try {
			long pos=iof.getFilePointer();
			iof.seek(0);
			int result=iof.readInt();
			iof.seek(pos);
			return result;
		} catch (IOException iox) {
			System.err.println("IO Error or end of file achieved");
			//e.printStackTrace();
		}
		return -1;
	}

	//Close the File
	public void close() throws IOException {
		iof.close();
	}
	
	//Iterator Functionality
	public UserIterator getIterator() {
		return new UserIterator(this);
	}
	void setPointer(int i) {
		try {
			iof.seek(i);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	RandomAccessFile getFile() {
		return this.iof;
	}
}
